package club.janna.springboot.study.util;

import java.util.concurrent.atomic.AtomicInteger;

public abstract class AbstractArrayChooser<T> implements Chooser<T> {
    private final T[] arr;

    public AbstractArrayChooser(T[] arr) {
        this.arr = arr;
    }

    /**
     * 选取下一个索引
     * @param length 数组的长度
     * @return
     */
    public abstract int nextIndex(int length);

    @Override
    public T next() {
        return arr[nextIndex(arr.length)];
    }

    /**
     * 二的幂 数组选择器
     * @param <T>
     */
    public static class PowerOfTwoArrayChooser<T> extends AbstractArrayChooser<T> {
        private AtomicInteger count = new AtomicInteger(0);

        public PowerOfTwoArrayChooser(T[] arr) {
            super(arr);
        }

        @Override
        public int nextIndex(int length) {
            return count.getAndIncrement() & (length - 1);
        }
    }

    public static class SingleArrayChooser<T> extends AbstractArrayChooser<T> {
        public SingleArrayChooser(T[] arr) {
            super(arr);
        }

        @Override
        public int nextIndex(int length) {
            return 0;
        }
    }

    public static class GenericArrayChooser<T> extends AbstractArrayChooser<T> {
        private AtomicInteger count = new AtomicInteger(0);

        public GenericArrayChooser(T[] arr) {
            super(arr);
        }

        @Override
        public int nextIndex(int length) {
//            int c = count.getAndIncrement();
//            if(c >>> 31 == 1) // 如果是负数，说明int溢出
//                for(;;) { // 修改为0
//                    c = count.get();
//                    if(c >>> 31 == 0)
//                        break;
//                    count.compareAndSet(c, 0);
//                }
            return Math.abs(count.getAndIncrement() % length);
        }
    }
}
